//
//  SCPopOverView.swift
//  scfriend
//
//  Created by wulanzhou on 2017/8/3.
//  Copyright © 2017年 wulanzhou. All rights reserved.
//

import UIKit

typealias SCPopOverMenuDoneBlock = (_ index:Int) -> ()
typealias SCPopOverMenuDismissBlock = () -> ()

public enum SCPopOverMenuArrowDirection{

    case MenuArrowDirectionUp
    case MenuArrowDirectionDown
}

class FTPopOverMenuConfiguration: NSObject {
    
    // unchangeable, change them at your own risk
    
    var backgroundColor:UIColor = UIColor.clear
    var menuIconSize:CGFloat = 24.0
    var menuIconMargin:CGFloat = 6.0
    var menuRowHeight:CGFloat = 40.0
    var menuWidth:CGFloat = 120.0
    var textColor:UIColor = UIColor.black
    var tintColor:UIColor = UIColor.init(red: 42/255.0, green: 173/255.0, blue: 240/255.0, alpha: 0.5)
    var borderWidth:CGFloat = 0.8
    var borderColor:UIColor = UIColor.init(red: 42/255.0, green: 173/255.0, blue: 240/255.0, alpha: 0.5)
    var textFont:UIFont = UIFont.systemFont(ofSize: 14.0)
    var textAlignment:NSTextAlignment = .left
    var ignoreImageOriginalColor:Bool = false
    var allowRoundedArrow:Bool = false
    var animationDuration:TimeInterval = 0.2
    
    var menuArrowWidth:CGFloat = 8.0
    var menuArrowHeight:CGFloat = 10.0
    var menuArrowWidth_R:CGFloat = 12.0
    var menuArrowHeight_R:CGFloat = 12.0
    var menuArrowRoundRadius:CGFloat = 4.0
    
    // changeable
    var margin:CGFloat = 4.0
    var menuTextMargin:CGFloat = 6.0
    var menuCornerRadius:CGFloat = 5.0
    
    static let defaultConfiguration = FTPopOverMenuConfiguration()
    private override init() {
        
    }
    
}

class FTPopOverMenuCell: UITableViewCell {
    
    private lazy var iconImageView:UIImageView = {
    
        let imgView = UIImageView.init(frame: CGRect.zero)
        imgView.backgroundColor = UIColor.clear
        imgView.contentMode = .scaleAspectFit
        return imgView
    }()
    
    private lazy var menuNameLabel:UILabel = {
        
        let lab = UILabel.init(frame: CGRect.zero)
        lab.backgroundColor = UIColor.clear
        return lab
    }()
    
    private func setupName(menuName:String,menuImage:AnyObject?){
    
        
        let configuration = FTPopOverMenuConfiguration.defaultConfiguration
        
        let margin:CGFloat = (configuration.menuRowHeight - configuration.menuIconSize)/2.0
        let iconImageRect:CGRect = CGRect(x:configuration.menuIconMargin, y:margin, width:configuration.menuIconSize, height:configuration.menuIconSize);
        let menuNameX:CGFloat = iconImageRect.origin.x + iconImageRect.size.width + configuration.menuTextMargin;
        var menuNameRect:CGRect = CGRect(x:menuNameX, y:0, width:configuration.menuWidth - menuNameX - configuration.menuTextMargin, height:configuration.menuRowHeight);
        
        if (menuImage == nil) {
            menuNameRect = CGRect(x:configuration.menuTextMargin, y:0, width:configuration.menuWidth - configuration.menuTextMargin*2, height:configuration.menuRowHeight);
        }else{
            self.iconImageView.frame = iconImageRect
            self.iconImageView.tintColor = configuration.textColor
            
            self.getImageWithResource(resource: menuImage, completion: { (image:UIImage?) in
                
                if (configuration.ignoreImageOriginalColor) {
                   
                    //[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
                }
                self.iconImageView.image = image
            })
            self.contentView.addSubview(self.iconImageView)
            
        }
        self.menuNameLabel.frame = menuNameRect;
        self.menuNameLabel.font = configuration.textFont;
        self.menuNameLabel.textColor = configuration.textColor;
        self.menuNameLabel.textAlignment = configuration.textAlignment;
        self.menuNameLabel.text = menuName;
        self.contentView.addSubview(self.menuNameLabel)

    }
    
    init(style:UITableViewCellStyle,reuseIdentifier:String,menuName:String,menuImage:AnyObject?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.backgroundColor = UIColor.clear
        self.setupName(menuName: menuName, menuImage: menuImage)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //MAKE:私有方法
    private func getImageWithResource(resource:AnyObject?,completion:((UIImage?) -> ())?){
    
        if let image = resource as? UIImage {
           completion?(image)
        }else if let str = resource as? String {
            
            if str.hasPrefix("http"){
                self.downloadImageWithURL(url: URL.init(string: str)!, completion: completion)
            }else{
               completion?(UIImage.init(named: str))
            }
        
        }else if let url = resource as? URL {
            self.downloadImageWithURL(url: url, completion: completion)
        
        }else{
           completion?(nil)
        }
        
    }
    
    private func downloadImageWithURL(url:URL,completion:((UIImage?) -> ())?){
        
        if (self.isExitImageForImageURL(url: url)){
            let filePath = self.filePathForImageURL(url: url)
            completion?(UIImage.init(contentsOfFile: filePath))
        
        }else{
            
            DispatchQueue.global().async {
                
                do {
                    let data = try Data.init(contentsOf: url)
                    if let image = UIImage.init(data: data ) {
                        
                        if let imgData = UIImagePNGRepresentation(image) as NSData? {
                            imgData.write(toFile: self.filePathForImageURL(url: url), atomically: true)
                            
                            DispatchQueue.main.async {
                                completion?(image)
                            }
                        }
                    }
                    
                }catch{
                    
                }
                
            }
            
        
            
        }
    
    }
    
    private func isExitImageForImageURL(url:URL) -> Bool {
    
       return FileManager.default.fileExists(atPath: self.filePathForImageURL(url: url))
    }
    
    private func filePathForImageURL(url:URL) -> String {
    
        let doc = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true))[0] as NSString
        let diskCachePath = doc.appendingPathComponent("com.SCPopOverMenuImageCache") as String
        if (!FileManager.default.fileExists(atPath: diskCachePath)){
        
            do{
                //创建目录
                try FileManager.default.createDirectory(atPath: diskCachePath, withIntermediateDirectories: true, attributes: nil)
                print("创建目录成功")
            }catch{
                print("创建目录失败")
            }
        }
        let data = url.absoluteString.data(using: .utf8)
        let pathComponent = data?.base64EncodedString(options: .init(rawValue: 0))
        let filePath = (diskCachePath as NSString).appendingPathComponent(pathComponent!)
        
        return filePath
    }
}


class SCPopOverMenuView: UIControl,UITableViewDelegate,UITableViewDataSource {
    
    var menuStringArray:[String] = []
    var menuImageArray:[String]?
    var arrowDirection:SCPopOverMenuArrowDirection?
    var doneBlock:SCPopOverMenuDoneBlock?
    var backgroundLayer:CAShapeLayer?
    
    private lazy var menuTableView:UITableView = {
    
        let menuTable = UITableView.init(frame: CGRect.zero, style: .plain)
        menuTable.backgroundColor = FTPopOverMenuConfiguration.defaultConfiguration.backgroundColor
        menuTable.separatorColor = UIColor.gray
        menuTable.layer.cornerRadius = FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius
        menuTable.isScrollEnabled = false
        menuTable.clipsToBounds = true
        menuTable.delegate = self
        menuTable.dataSource = self
        return menuTable
    }()
    
    private func menuArrowWidth() ->CGFloat {
    
        return FTPopOverMenuConfiguration.defaultConfiguration.allowRoundedArrow ? FTPopOverMenuConfiguration.defaultConfiguration.menuArrowWidth_R:FTPopOverMenuConfiguration.defaultConfiguration.menuArrowWidth
    }
    
    private func menuArrowHeight() -> CGFloat {
        return FTPopOverMenuConfiguration.defaultConfiguration.allowRoundedArrow ? FTPopOverMenuConfiguration.defaultConfiguration.menuArrowHeight_R:FTPopOverMenuConfiguration.defaultConfiguration.menuArrowHeight
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.addSubview(self.menuTableView)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    func show(frame:CGRect,anglePoint:CGPoint,withNameArray:[String],imageNameArray:[String]?,shouldAutoScroll:Bool,arrowDirection:SCPopOverMenuArrowDirection,doneBlock:@escaping SCPopOverMenuDoneBlock) {
        self.frame = frame
        self.menuStringArray = withNameArray
        self.menuImageArray = imageNameArray
        self.arrowDirection = arrowDirection
        self.menuTableView.isScrollEnabled = shouldAutoScroll
        self.doneBlock = doneBlock
        
        var menuRect = CGRect(x: 0, y: self.menuArrowHeight(), width: self.frame.size.width, height: self.frame.size.height - self.menuArrowHeight())
        if (self.arrowDirection == SCPopOverMenuArrowDirection.MenuArrowDirectionDown){
             menuRect = CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height - self.menuArrowHeight())
        }
        
        self.menuTableView.frame = menuRect
        self.menuTableView.reloadData()
        self.drawBackgroundLayer(anglePoint: anglePoint)
        
    }
    
    private func drawBackgroundLayer(anglePoint:CGPoint){
        
        if(backgroundLayer != nil){
            backgroundLayer!.removeFromSuperlayer()
        }
        
        let path:UIBezierPath = UIBezierPath.init()
        let allowRoundedArrow:Bool = FTPopOverMenuConfiguration.defaultConfiguration.allowRoundedArrow
        let offset:CGFloat = 2.0 * FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius * CGFloat(sinf(Float(Double.pi/4/2.0)))
        let roundcenterHeight:CGFloat = offset + FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius * CGFloat(sqrtf(2.0))
        var roundcenterPoint:CGPoint = CGPoint(x: anglePoint.x, y: roundcenterHeight)
            //CGPoint(anglePoint.x, roundcenterHeight);
        
        
        if(self.arrowDirection == .MenuArrowDirectionUp){
            if (allowRoundedArrow) {
                path.addArc(withCenter: CGPoint(x:anglePoint.x + self.menuArrowWidth(), y:self.menuArrowHeight() - 2.0 * FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius), radius: 2.0 * FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius, startAngle: CGFloat(Double.pi/2), endAngle: CGFloat(Double.pi/4 * 3.0), clockwise: true)
                
                let px1:CGFloat = anglePoint.x + CGFloat(Float(FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius)/sqrtf(2.0))
                let py1:CGFloat = roundcenterPoint.y - CGFloat(Float(FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius)/sqrtf(2.0))
                path.addLine(to: CGPoint(x: px1, y: py1))
                            
                path.addArc(withCenter:roundcenterPoint, radius:FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius,startAngle:CGFloat(Double.pi/4) * 7.0, endAngle:CGFloat(Double.pi/4) * 5.0, clockwise:false)
                
                let px2:CGFloat = anglePoint.x - self.menuArrowWidth() + CGFloat(Float(offset) * (1.0 + 1.0/sqrtf(2.0)))
                let py2:CGFloat = self.menuArrowHeight() - CGFloat(Float(offset)/sqrtf(2.0))
                path.addLine(to:CGPoint(x:px2, y:py2))
                
                path.addArc(withCenter:CGPoint(x:anglePoint.x - self.menuArrowWidth(), y:self.menuArrowHeight() - 2.0 * FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius), radius:2.0 * FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius, startAngle:CGFloat(Double.pi/4), endAngle:CGFloat(Double.pi/2), clockwise:true)
                
               
            } else {
                
                path.move(to: CGPoint(x: anglePoint.x + self.menuArrowWidth(), y: self.menuArrowHeight()))
                path.addLine(to: anglePoint)
                path.move(to: CGPoint(x: anglePoint.x - self.menuArrowWidth(), y: self.menuArrowHeight()))
            }
            
            path.addLine(to: CGPoint(x: FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, y: self.menuArrowHeight()))
            path.addArc(withCenter: CGPoint(x:FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, y:self.menuArrowHeight() + FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius), radius:FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, startAngle: -(CGFloat)(Double.pi/2), endAngle: -(CGFloat)(Double.pi), clockwise: false)
            path.addLine(to: CGPoint(x: 0, y: self.bounds.size.height - FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius))
            path.addArc(withCenter: CGPoint(x:FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, y:self.bounds.size.height - FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius), radius:FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, startAngle: CGFloat(Double.pi), endAngle: CGFloat(Double.pi/2), clockwise: false)
            path.addLine(to: CGPoint(x: self.bounds.size.width - FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, y: self.bounds.size.height))
            path.addArc(withCenter: CGPoint(x:self.bounds.size.width - FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, y:self.bounds.size.height - FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius), radius:FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, startAngle: CGFloat(Double.pi/2), endAngle: 0, clockwise: false)
            path.addLine(to: CGPoint(x: self.bounds.size.width, y: FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius + self.menuArrowHeight()))
            path.addArc(withCenter: CGPoint(x:self.bounds.size.width - FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, y:self.menuArrowHeight() + FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius), radius:FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, startAngle: 0, endAngle: -(CGFloat)(Double.pi/2), clockwise: false)
           
            path.close()
            //[path closePath];
        }
        
        if(self.arrowDirection == .MenuArrowDirectionDown){
            
            roundcenterPoint = CGPoint(x:anglePoint.x,y:anglePoint.y - roundcenterHeight)
            
            if (allowRoundedArrow) {
                path.addArc(withCenter: CGPoint(x:anglePoint.x + self.menuArrowWidth(), y:anglePoint.y - self.menuArrowHeight() + 2.0 * FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius), radius: 2.0 * FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius, startAngle: CGFloat(Double.pi/2) * 3.0, endAngle: CGFloat(Double.pi/4 * 5.0), clockwise: false)
                
                let ax1:CGFloat = anglePoint.x + CGFloat(Float(FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius)/sqrtf(2.0))
                let ay1:CGFloat = roundcenterPoint.y + CGFloat(Float(FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius)/sqrtf(2.0))
                path.addLine(to: CGPoint(x: ax1, y: ay1))
                
                path.addArc(withCenter: roundcenterPoint, radius: FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius, startAngle: CGFloat(Double.pi/4), endAngle: CGFloat(Double.pi/4) * 3.0, clockwise: true)
                
                let ax2:CGFloat = anglePoint.x - self.menuArrowWidth() + CGFloat(Float(offset) * (1.0 + 1.0/sqrtf(2.0)))
                let ay2:CGFloat = anglePoint.y - self.menuArrowHeight() + CGFloat(Float(offset)/sqrtf(2.0))
                path.addLine(to: CGPoint(x: ax2, y: ay2))
                
                path.addArc(withCenter: CGPoint(x: anglePoint.x - self.menuArrowWidth(), y: anglePoint.y - self.menuArrowHeight() + 2.0 * FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius), radius: 2.0 * FTPopOverMenuConfiguration.defaultConfiguration.menuArrowRoundRadius, startAngle: CGFloat(Double.pi/4 * 7.0), endAngle: CGFloat(Double.pi/2 * 3.0), clockwise: false)
                
            } else {
                
                path.move(to: CGPoint(x: anglePoint.x + self.menuArrowWidth(), y: anglePoint.y - self.menuArrowHeight()))
                path.addLine(to: anglePoint)
                path.addLine(to: CGPoint(x: anglePoint.x - self.menuArrowWidth(), y: anglePoint.y - self.menuArrowHeight()))
            }
            
            path.addLine(to: CGPoint(x: FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, y: anglePoint.y - self.menuArrowHeight()))
            path.addArc(withCenter: CGPoint(x:FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius,y:anglePoint.y - self.menuArrowHeight() - FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius), radius: FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, startAngle: CGFloat(Double.pi/2), endAngle: CGFloat(Double.pi), clockwise: true)
            path.addLine(to: CGPoint(x: 0, y: FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius))
           
            path.addArc(withCenter: CGPoint(x:FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius,y:FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius), radius: FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, startAngle: CGFloat(Double.pi), endAngle: -CGFloat(Double.pi/2), clockwise: true)
            path.addLine(to: CGPoint(x: self.bounds.size.width - FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, y: 0))
            path.addArc(withCenter: CGPoint(x:self.bounds.size.width - FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius,y:FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius), radius: FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, startAngle: -CGFloat(Double.pi/2), endAngle: 0, clockwise: true)
            path.addLine(to: CGPoint(x: self.bounds.size.width, y: anglePoint.y - (FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius + self.menuArrowHeight())))
            path.addArc(withCenter: CGPoint(x:self.bounds.size.width - FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius,y:anglePoint.y - (FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius + self.menuArrowHeight())), radius: FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius, startAngle: 0, endAngle: CGFloat(Double.pi/2), clockwise: true)
            path.close()
            

            
        }
        
        backgroundLayer = CAShapeLayer.init()
        backgroundLayer?.path = path.cgPath
        backgroundLayer?.lineWidth = FTPopOverMenuConfiguration.defaultConfiguration.borderWidth
        backgroundLayer?.fillColor = FTPopOverMenuConfiguration.defaultConfiguration.tintColor.cgColor
        backgroundLayer?.strokeColor = FTPopOverMenuConfiguration.defaultConfiguration.borderColor.cgColor
        self.layer.insertSublayer(backgroundLayer!, at: 0)
    }
    
    //MARK: UITableViewDelegate,UITableViewDataSource
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 0
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return FTPopOverMenuConfiguration.defaultConfiguration.menuRowHeight
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("self.menuStringArray.count = \(self.menuStringArray.count)")
        return self.menuStringArray.count
    }
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 0
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var menuImage:AnyObject?
        if (self.menuImageArray != nil && self.menuImageArray!.count - 1 >= indexPath.row) {
            menuImage = self.menuImageArray![indexPath.row] as AnyObject
        }
        
        let menuCell:FTPopOverMenuCell = FTPopOverMenuCell.init(style: .default, reuseIdentifier: "SCPopOverMenuTableViewCellIndentifier", menuName: self.menuStringArray[indexPath.row], menuImage: menuImage)
        
        
        if (indexPath.row == self.menuStringArray.count-1) {
            menuCell.separatorInset = UIEdgeInsetsMake(0, self.bounds.size.width, 0, 0)
        }else{
            menuCell.separatorInset = UIEdgeInsetsMake(0, FTPopOverMenuConfiguration.defaultConfiguration.menuTextMargin, 0, FTPopOverMenuConfiguration.defaultConfiguration.menuTextMargin)
        }
        return menuCell
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        self.doneBlock?(indexPath.row)
    }
    
}

class SCPopOverMenu: NSObject,UIGestureRecognizerDelegate {
    
    private lazy var backgroundWindow:UIWindow? = {
    
        var win:UIWindow? = UIApplication.shared.keyWindow
        /**
        var delegate:UIApplicationDelegate? = UIApplication.shared.delegate
        if(win == nil && (delegate?.responds(to: #selector(UIWindow())))!){
            win = delegate?.perform(#selector(window))
        }
        **/
        return win
    
    }()
    
    private lazy var backgroundView:UIView = {
        
        let bgView:UIView = UIView.init(frame: UIScreen.main.bounds)
        let tap:UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(onBackgroundViewTapped(gesture:)))
        tap.delegate = self
        bgView.addGestureRecognizer(tap)
        return bgView
    
    }()
    
    
    private lazy var popMenuView:SCPopOverMenuView = {
       
        let menuView = SCPopOverMenuView.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        menuView.alpha = 0.0
        return menuView
    
    }()
    
    var doneBlock:SCPopOverMenuDoneBlock?
    var dismissBlock:SCPopOverMenuDismissBlock?
 
    var sender:UIView?
    var senderFrame:CGRect = CGRect.zero
    var menuArray:[String] = []
    var menuImageArray:[String]?
    var isCurrentlyOnScreen:Bool = false
    
    static let sharedInstance = SCPopOverMenu()
    override init() {
        super.init()
        
        NotificationCenter.default.addObserver(self, selector: #selector(onChangeStatusBarOrientationNotification(notify:)), name:.UIApplicationDidChangeStatusBarOrientation, object: nil)
    }
    
    class func showForSender(sender:UIView,menuArray:[String],doneBlock:SCPopOverMenuDoneBlock?,dismissBlock:SCPopOverMenuDismissBlock?)  {
        
        
        self.sharedInstance.showForSender(sender: sender, senderFrame: CGRect.null, menuArray: menuArray, imageNameArray: nil, doneBlock: doneBlock, dismissBlock: dismissBlock)
    }
    
    class func showForSender(sender:UIView,menuArray:[String],imageArray:[String]?,doneBlock:SCPopOverMenuDoneBlock?,dismissBlock:SCPopOverMenuDismissBlock?) {
        
        self.sharedInstance.showForSender(sender: sender, senderFrame: CGRect.null, menuArray: menuArray, imageNameArray: imageArray, doneBlock: doneBlock, dismissBlock: dismissBlock)
    
    }
    
    class func showFromEvent (event:UIEvent,menuArray:[String],doneBlock:SCPopOverMenuDoneBlock?,dismissBlock:SCPopOverMenuDismissBlock?){
        
        let t:UITouch = (event.allTouches! as NSSet).anyObject() as! UITouch
        self.sharedInstance.showForSender(sender: t.view, senderFrame: CGRect.null, menuArray: menuArray, imageNameArray: nil, doneBlock: doneBlock, dismissBlock: dismissBlock)
    }
    
    class func showFromEvent (event:UIEvent,menuArray:[String],imageArray:[String]?,doneBlock:SCPopOverMenuDoneBlock?,dismissBlock:SCPopOverMenuDismissBlock?){
        
        let t:UITouch = (event.allTouches! as NSSet).anyObject() as! UITouch
        self.sharedInstance.showForSender(sender: t.view, senderFrame: CGRect.null, menuArray: menuArray, imageNameArray: imageArray, doneBlock: doneBlock, dismissBlock: dismissBlock)
    }
    
    class func showFromSenderFrame(frame:CGRect,menuArray:[String],doneBlock:SCPopOverMenuDoneBlock?,dismissBlock:SCPopOverMenuDismissBlock?){
    
        self.sharedInstance.showForSender(sender: nil, senderFrame: frame, menuArray: menuArray, imageNameArray: nil, doneBlock: doneBlock, dismissBlock: dismissBlock)
    }
    
    class func showFromSenderFrame(frame:CGRect,menuArray:[String],imageArray:[String]?,doneBlock:SCPopOverMenuDoneBlock?,dismissBlock:SCPopOverMenuDismissBlock?){
        
        self.sharedInstance.showForSender(sender: nil, senderFrame: frame, menuArray: menuArray, imageNameArray: imageArray, doneBlock: doneBlock, dismissBlock: dismissBlock)
        
    }
    class func dismiss() {
    
        self.sharedInstance.dismiss()
    }
    
    private func menuArrowWidth() -> CGFloat{
        
        return FTPopOverMenuConfiguration.defaultConfiguration.allowRoundedArrow ? FTPopOverMenuConfiguration.defaultConfiguration.menuArrowWidth_R : FTPopOverMenuConfiguration.defaultConfiguration.menuArrowWidth;
    }
    
    private func menuArrowHeight() -> CGFloat{
        
        return FTPopOverMenuConfiguration.defaultConfiguration.allowRoundedArrow ? FTPopOverMenuConfiguration.defaultConfiguration.menuArrowHeight_R : FTPopOverMenuConfiguration.defaultConfiguration.menuArrowHeight;
    
    }
    
    @objc private func onChangeStatusBarOrientationNotification(notify:NSNotification){
        
        if (self.isCurrentlyOnScreen) {
        
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
                self.adjustPopOverMenu()
            })
        }
    }
    
    func showForSender(sender:UIView?,senderFrame:CGRect,menuArray:[String],imageNameArray:[String]?,doneBlock:SCPopOverMenuDoneBlock?,dismissBlock:SCPopOverMenuDismissBlock?) {
        
        DispatchQueue.global().async {
            DispatchQueue.main.async {
                
                self.backgroundView.addSubview(self.popMenuView)
                self.backgroundWindow?.addSubview(self.backgroundView)
                self.sender = sender
                self.senderFrame = senderFrame
                self.menuArray = menuArray
                self.menuImageArray = imageNameArray
                
                self.doneBlock = doneBlock
                self.dismissBlock = dismissBlock
                self.adjustPopOverMenu()
            }
        }
        
       
    }
    
    
    
    @objc private func onBackgroundViewTapped(gesture:UIGestureRecognizer){
        self.dismiss()
    }
    
   
    
    private func adjustPopOverMenu(){
        
        self.backgroundView.frame = UIScreen.main.bounds
        var senderRect:CGRect
        if(self.sender != nil){
            senderRect = (self.sender?.superview?.convert(self.sender!.frame, to: self.backgroundView))!
        }else{
            senderRect = self.senderFrame
        }
        if (senderRect.origin.y > UIScreen.main.bounds.size.height) {
            senderRect.origin.y = UIScreen.main.bounds.size.height
        }
        
        let menuHeight:CGFloat = FTPopOverMenuConfiguration.defaultConfiguration.menuRowHeight * CGFloat(self.menuArray.count) + self.menuArrowHeight();
        var menuArrowPoint:CGPoint = CGPoint(x:senderRect.origin.x + (senderRect.size.width)/2, y: 0);
        var menuX:CGFloat = 0
        var menuRect:CGRect = CGRect.zero
        var shouldAutoScroll:Bool = false
        var arrowDirection:SCPopOverMenuArrowDirection
        
        if (senderRect.origin.y + senderRect.size.height/2  < UIScreen.main.bounds.size.height/2) {
            arrowDirection = .MenuArrowDirectionUp
            menuArrowPoint.y = 0
        }else{
            arrowDirection = .MenuArrowDirectionDown
            menuArrowPoint.y = menuHeight
            
        }
        
        if (menuArrowPoint.x + FTPopOverMenuConfiguration.defaultConfiguration.menuWidth/2 + FTPopOverMenuConfiguration.defaultConfiguration.margin > UIScreen.main.bounds.size.width) {
            menuArrowPoint.x = min(menuArrowPoint.x - (UIScreen.main.bounds.size.width - FTPopOverMenuConfiguration.defaultConfiguration.menuWidth - FTPopOverMenuConfiguration.defaultConfiguration.margin),FTPopOverMenuConfiguration.defaultConfiguration.menuWidth - self.menuArrowWidth() - FTPopOverMenuConfiguration.defaultConfiguration.margin)
            menuX = UIScreen.main.bounds.size.width - FTPopOverMenuConfiguration.defaultConfiguration.menuWidth - FTPopOverMenuConfiguration.defaultConfiguration.margin
        }else if ( menuArrowPoint.x - FTPopOverMenuConfiguration.defaultConfiguration.menuWidth/2 - FTPopOverMenuConfiguration.defaultConfiguration.margin < 0){
            menuArrowPoint.x = max( FTPopOverMenuConfiguration.defaultConfiguration.menuCornerRadius + self.menuArrowWidth(), menuArrowPoint.x - FTPopOverMenuConfiguration.defaultConfiguration.margin)
            menuX = FTPopOverMenuConfiguration.defaultConfiguration.margin
        }else{
            menuArrowPoint.x = FTPopOverMenuConfiguration.defaultConfiguration.menuWidth/2
            menuX = senderRect.origin.x + (senderRect.size.width)/2 - FTPopOverMenuConfiguration.defaultConfiguration.menuWidth/2
        }
        
        if(arrowDirection == .MenuArrowDirectionUp) {
        
            menuRect = CGRect(x:menuX, y:(senderRect.origin.y + senderRect.size.height), width:FTPopOverMenuConfiguration.defaultConfiguration.menuWidth, height:menuHeight)
            // if too long and is out of screen
            if (menuRect.origin.y + menuRect.size.height > UIScreen.main.bounds.size.height) {
                menuRect = CGRect(x:menuX, y:(senderRect.origin.y + senderRect.size.height), width:FTPopOverMenuConfiguration.defaultConfiguration.menuWidth, height:UIScreen.main.bounds.size.height - menuRect.origin.y - FTPopOverMenuConfiguration.defaultConfiguration.margin)
                shouldAutoScroll = true
            }
        
        }else{
            
            menuRect = CGRect(x:menuX,y: (senderRect.origin.y - menuHeight), width:FTPopOverMenuConfiguration.defaultConfiguration.menuWidth, height:menuHeight)
            // if too long and is out of screen
            if (menuRect.origin.y  < 0) {
                menuRect = CGRect(x:menuX, y:FTPopOverMenuConfiguration.defaultConfiguration.margin,width:FTPopOverMenuConfiguration.defaultConfiguration.menuWidth, height:senderRect.origin.y - FTPopOverMenuConfiguration.defaultConfiguration.margin)
                menuArrowPoint.y = senderRect.origin.y
                shouldAutoScroll = true
            }
        }
        
        self.prepareToShow(menuRect: menuRect, menuArrowPoint: menuArrowPoint, shouldAutoScroll: shouldAutoScroll, arrowDirection: arrowDirection)
        self.show()
    }
    
    func prepareToShow(menuRect:CGRect,menuArrowPoint:CGPoint,shouldAutoScroll:Bool,arrowDirection:SCPopOverMenuArrowDirection) {
        
        var anchorPoint:CGPoint = CGPoint(x:menuArrowPoint.x/menuRect.size.width, y:0)
        if (arrowDirection == .MenuArrowDirectionDown) {
            anchorPoint = CGPoint(x:menuArrowPoint.x/menuRect.size.width, y:1)
        }
        self.popMenuView.transform = CGAffineTransform(scaleX: 1, y: 1);

        self.popMenuView.show(frame: menuRect, anglePoint: menuArrowPoint, withNameArray: self.menuArray, imageNameArray: self.menuImageArray, shouldAutoScroll: shouldAutoScroll, arrowDirection: arrowDirection) { (index:NSInteger) in
            self.doneActionWithSelectedIndex(selectedIndex: index)
        }
        
        self.setAnchorPoint(anchorPoint: anchorPoint, forView: self.popMenuView)
        
        self.popMenuView.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
        
    }
    
    private func setAnchorPoint(anchorPoint:CGPoint,forView:UIView){
        
        var newPoint:CGPoint = CGPoint(x:forView.bounds.size.width * anchorPoint.x,y:forView.bounds.size.height * anchorPoint.y)
        var oldPoint:CGPoint = CGPoint(x:forView.bounds.size.width * forView.layer.anchorPoint.x,y:forView.bounds.size.height * forView.layer.anchorPoint.y)
        
        newPoint = newPoint.applying(forView.transform)
        oldPoint = oldPoint.applying(forView.transform)
        
        var position:CGPoint = forView.layer.position
        
        position.x -= oldPoint.x
        position.x += newPoint.x
        
        position.y -= oldPoint.y
        position.y += newPoint.y
        
        forView.layer.position = position
        forView.layer.anchorPoint = anchorPoint
    
    }
    
    //MAKE UIGestureRecognizerDelegate
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        
        let point:CGPoint = touch.location(in: self.popMenuView)
        
        //touch.view.self
        if(NSStringFromClass(touch.view!.classForCoder) == "UITableViewCellContentView"){
            
            return false
            
        }else if(CGRect(x: 0, y: 0, width: FTPopOverMenuConfiguration.defaultConfiguration.menuWidth, height: FTPopOverMenuConfiguration.defaultConfiguration.menuRowHeight).contains(point)){
            
            self.doneActionWithSelectedIndex(selectedIndex: 0)
            return false
        }
        return true
    }
    
    //mark - show animation
    func show() {
        
        self.isCurrentlyOnScreen = true
        UIView.animate(withDuration: FTPopOverMenuConfiguration.defaultConfiguration.animationDuration) {
            self.popMenuView.alpha = 1.0
            self.popMenuView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
        }
    }
    
    func dismiss()
    {
        self.isCurrentlyOnScreen = false
        self.doneActionWithSelectedIndex(selectedIndex: -1)
    }
    
    //mark - doneActionWithSelectedIndex
    func doneActionWithSelectedIndex(selectedIndex:NSInteger)  {
        UIView.animate(withDuration: FTPopOverMenuConfiguration.defaultConfiguration.animationDuration, animations: {
            self.popMenuView.alpha = 0.0
            self.popMenuView.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
            
        }) { (finished:Bool) in
            
            if(finished){
            
                self.popMenuView.removeFromSuperview()
                self.backgroundView.removeFromSuperview()
                if (selectedIndex < 0) {
                    self.dismissBlock?()
                }else{
                    self.doneBlock?(selectedIndex)
                }
            }
            
        }
    }

    
}


